home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
prev
/
prev.lha
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-20
|
9KB
|
448 lines
#include <stdio.h>
#include <math.h>
#ifdef VMS
#include <types.h>
#else
#include <sys/types.h>
#endif
#ifdef MSC
#include <fcntl.h>
#include <string.h>
#define rindex strrchr
#else
#ifdef SYSV
#include <fcntl.h>
#else
#ifdef VMS
#include <file.h>
#else
#include <sys/file.h>
#endif
#endif
#endif
#ifdef VMS
#include <string.h>
#define rindex strrchr
#endif
#ifdef MIPS
#include <string.h>
#define rindex strrchr
#endif
#ifdef TIME_STATS
#include <sys/times.h>
#endif
#include <vogle.h>
#include "art.h"
#include "objs.h"
#include "macro.h"
#include "gram.h"
#include "random.h"
extern char *rindex();
extern hlist *trace();
extern void shade();
extern time_t time();
extern object *treeinit();
#ifndef VMS
FILE *logfile = stdout;
#else
FILE *logfile;
#endif
int linecount; /* line counter for parser */
object *oblist; /* object list */
object *treeobjs, *otherobjs; /* bsp-able and non-bsp-able objects */
light *lights; /* lights list */
symbol *ostack[STACKSIZE], /* object def stack */
**ostackp;
attr astack[STACKSIZE], /* attribute stack */
*astackp;
mats mstack[STACKSIZE], /* transformation stack */
*mstackp;
char *title; /* title of picture */
char currentfile[MESLEN]; /* name of current "input" file */
int raysperpix = 1; /* number of rays per pixel */
int maxhitlevel = 6; /* max number of rays traced in reflection */
long filetype = PIX_RLE; /* output file format */
short raynumber = 1; /* initial raynumber */
float screenx = 1.0, /* half screen width */
screeny = 1.0; /* half screen height */
float tolerance; /* tolerance value */
int maxtreedepth = 35; /* max depth for kd tree */
int orthographic = FALSE; /* orthographic or perspective projection */
/*
* ambient colour and background pixel stuff
*/
colour ambient;
colour backcol = { 0.0, 0.0, 0.0 };
/*
* light falloff
*/
float falloff = 0.0;
/*
* global refractive index
*/
float ri = 1.0;
/*
* pointer to the free list for hit structures
*/
hlist *fhlist;
/*
* details for the primary rays
*/
vector org;
vector viewup = { 0.0, 1.0, 0.0 };
matrix trans = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
/*
* shading stack
*/
shadedata *sstack, *sstackp;
/*
* haze stuff
*/
float fogfactor = 0.0, /* the fog factor */
rfactor = 0.03; /* the mysterious "r" factor */
colour hazecolour = { 1.0, 1.0, 1.0 }; /* the haze colour */
float sourceradius; /* For ripple texture */
/*
* temporary file pointer
*/
char *tmpname;
/*
* random number pointers
*/
float *randp = randtable,
*erandp = &randtable[sizeof(randtable) / sizeof(float)];
/*
* function pointer tables for intersections, normals, etc...
*/
hlist *(*intersects[NUM_OBJS])();
void (*normal[NUM_OBJS])();
void (*tilefun[NUM_OBJS])();
int checkbbox[NUM_OBJS]; /* should we check bounding box of this type */
/*
* x, y offsets, scale, and sampleing
*/
static int xoff, yoff;
static float xscale, yscale;
static int ysperpix, xsperpix;
/*
* frame id extension
*/
char *frameid = "000";
/*
* default name
*/
char *defname = "pic.pix";
/*
* eyepoint stuff
*/
float fov = 90.0;
float twist = 0.0;
float near = 1.0;
vector eye = { 0.0, 0.0, 1.0 };
vector ref = { 0.0, 0.0, 0.0 };
int lookatdone = FALSE;
/*
* antialiasing stuff
*/
int pixelgrid = FALSE; /* pixel grid on or off */
static int extrarays, /* spare rays for jittering */
totrays; /* total number of rays per pixel */
static pixel *topline; /* scanline of sample grid at top of current scanline */
static pixel others[2]; /* bottom 2 samples of pixel grid */
static float averagefactor; /* number to divide final samples through by */
int longlines = 5; /* number of longitudanal lines to be drawn */
int latlines = 5; /* number of latitudanal lines to be drawn */
static int totobjs;
/*
* usage
*
* print out usage details for art.
*/
usage(s)
char *s;
{
if (s != (char *)NULL)
warning(s);
fatal("usage: art [-v] file.scn x_res y_res [-x x1 x2] [-y y1 y2] [-f frameid] [-o outputname] [-n]\n");
}
/*
* main driver
*/
main(ac, av)
int ac;
char *av[];
{
int y, x, chatty, indx, standardin, preprocess, nameset;
char *p, name[BUFSIZ], buf[BUFSIZ];
image *im;
FILE *infile;
unsigned char *red, *green, *blue, *alpha;
int i, fragment, xsize, ysize, xstart, xend, ystart, yend;
object *o, *nexto;
float k1, k2;
expression *e;
if (ac < 4)
usage((char *)NULL);
xsize = atoi(av[2]);
ysize = atoi(av[3]);
xstart = 0;
xend = xsize - 1;
ystart = ysize - 1;
yend = 0;
preprocess = TRUE;
nameset = FALSE;
standardin = FALSE;
fragment = FALSE;
/* check for other options */
for (i = 4; i < ac; i++) {
if (strcmp(av[i], "-y") == 0) {
if (av[i + 1] == (char *)NULL)
usage("art: -y requires two numbers.\n");
if (av[i + 2] == (char *)NULL)
usage("art: -y requires two numbers.\n");
ystart = ysize - atoi(av[i + 1]) - 1;
yend = ysize - atoi(av[i + 2]) - 1;
fragment = TRUE;
i += 2;
} else if (strcmp(av[i], "-x") == 0) {
if (av[i + 1] == (char *)NULL)
usage("art: -x requires two numbers.\n");
if (av[i + 2] == (char *)NULL)
usage("art: -x requires two numbers.\n");
xstart = atoi(av[i + 1]);
xend = atoi(av[i + 2]);
fragment = TRUE;
i += 2;
} else if (strcmp(av[i], "-f") == 0) {
if (av[i + 1] == (char *)NULL)
usage("art: -f requires frame identifier.\n");
frameid = av[i + 1];
i += 1;
} else if (strcmp(av[i], "-o") == 0) {
if (av[i + 1] == (char *)NULL)
usage("art: -o requires name.\n");
defname = av[i + 1];
nameset = TRUE;
i += 1;
} else if (strcmp(av[i], "-n") == 0) {
preprocess = FALSE;
} else {
sprintf(buf, "art: unknown option %s.\n", av[i]);
usage(buf);
}
}
/*
* set up window
*/
prefsize(xend - xstart + 1, ystart - yend + 1);
vinit("");
color(BLACK);
clear();
color(WHITE);
sourceradius = 100.0;
mident4(mstack[0].om);
mident4(mstack[0].vm);
mident4(mstack[0].ray2obj);
mident4(mstack[0].obj2ray);
mstack[0].maxscale = 1.0;
mstack[0].nscales.x = mstack[0].nscales.y = mstack[0].nscales.z = 1.0;
astack[0].s = (surface *)smalloc(sizeof(surface));
astack[0].s->falloff = astack[0].s->trans = astack[0].s->refl = 0.0;
astack[0].s->c.r = astack[0].s->c.g = astack[0].s->c.b = 1.0;
astack[0].s->a.r = astack[0].s->a.g = astack[0].s->a.b = 0.0;
astack[0].s->ri = astack[0].s->kd = 1.0;
astack[0].s->ks = 0.0;
astack[0].txtlist = (texture *)NULL;
astack[0].shadows = TRUE;
astack[0].slevel = 0;
mstackp = mstack;
astackp = astack;
ostackp = ostack;
linecount = 1;
if (strcmp(av[1], "-") == 0)
standardin = TRUE;
if (standardin || nameset) {
strcpy(name, defname);
if ((p = rindex(name, '.')) == (char *)NULL)
fatal("art: output file should end with \".pix\".\n");
} else {
strcpy(name, av[1]);
if ((p = rindex(name, '.')) == (char *)NULL)
fatal("art: input file should end with \".scn\".\n");
standardin = FALSE;
}
strcpy(p, ".log");
if ((logfile = fopen(name, "w")) == NULL) {
sprintf(buf, "art: unable to open %s for writing.\n", name);
fatal(buf);
}
if (!standardin) {
if (preprocess) {
strcpy(p, "XXXXXX");
mktemp(name);
if ((infile = fopen(name, "w")) == NULL) {
sprintf(buf, "art: unable to open temporary file %s.\n", name);
fatal(buf);
}
prepro(av[1], infile);
fclose(infile);
} else
strcpy(name, av[1]);
}
if (!standardin) {
#ifdef MSC
if ((infile = freopen(name, "rt", stdin)) == NULL) {
#else
if ((infile = freopen(name, "r", stdin)) == NULL) {
#endif
sprintf(buf, "art: unable to open file %s.\n", av[1]);
fatal(buf);
}
}
/*
* initialise variable symbol table
*/
e = (expression *)smalloc(sizeof(expression));
e->type = EXP_INT;
e->u.i = 'x';
defvar("x", e);
e = (expression *)smalloc(sizeof(expression));
e->type = EXP_INT;
e->u.i = 'y';
defvar("y", e);
e = (expression *)smalloc(sizeof(expression));
e->type = EXP_INT;
e->u.i = 'z';
defvar("z", e);
/*
* initialise object symbol table
*/
defobj("sphere", SPHERE, (details *)NULL);
defobj("ellipsoid", ELLIPSOID, (details *)NULL);
defobj("box", BOX, (details *)NULL);
defobj("torus", TORUS, (details *)NULL);
defobj("algebraic", ALGEBRAIC, (details *)NULL);
defobj("cylinder", CYLINDER, (details *)NULL);
defobj("cone", CONE, (details *)NULL);
defobj("superquadric", SUPERQUADRIC, (details *)NULL);
defobj("ring", RING, (details *)NULL);
defobj("disk", RING, (details *)NULL);
defobj("geometry", GEOMETRY, (details *)NULL);
defobj("polygon", POLYGON, (details *)NULL);
if (preprocess)
tmpname = name;
else
tmpname = (char *)NULL;
yyparse(); /* read in model and set oblist */
if (preprocess)
unlink(name);
if (!standardin)
fclose(infile); /* get rid of temp file (unlinked above) */
getkey();
vexit();
exit(ALLOK);
}
/*
* deflookat
*
* do the perspective and lookat.
*/
deflookat()
{
perspective(fov, 1.0, 0.0, 1.0e38);
translate(0.0, 0.0, -near);
up(viewup.x, viewup.y, viewup.z);
lookat(eye.x, eye.y, eye.z, ref.x, ref.y, ref.z, twist);
lookatdone = TRUE;
}